package pl.edu.agh.iosr.gamblingzone.adminpanel.action;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
import org.richfaces.model.ScrollableTableDataModel.SimpleRowKey;
import org.richfaces.model.selection.SimpleSelection;

import pl.edu.agh.iosr.gamblingzone.dao.AbstractEventDAO;
import pl.edu.agh.iosr.gamblingzone.dao.GroupDAO;
import pl.edu.agh.iosr.gamblingzone.model.AbstractEvent;
import pl.edu.agh.iosr.gamblingzone.model.Participant;
import pl.edu.agh.iosr.gamblingzone.utils.DAOFactory;

@Stateful
@Scope(ScopeType.SESSION)
@Name("eventsManage")
public class EventsManageAction implements EventsManage {

	@Logger
	Log log;

	/** The dao. */
	@In(required=true)
	DAOFactory dao;

	private List<AbstractEvent> all;
	private AbstractEventDAO eventDAO;
	private AbstractEvent currentEvent;
	private List<Participant> participants;
	private List<Participant> tempEvent;
	private String tempProb;
	private Map<Participant, Double> tempMap;
	private SimpleSelection selection;
	private Date closingDate;

	public Date getClosingDate() {
		return closingDate;
	}

	public void setClosingDate(Date closingDate) {
		this.closingDate = closingDate;
	}

	public void setSelection(SimpleSelection selection) {
		this.selection = selection;
	}

	private double calcCurrentProbability() {
		double res = 0.0;
		for (Double elem : tempMap.values()) {
			res += elem;
		}
		return res;
	}
	
	public void addToEvent(Participant participant) {
		double x = calcCurrentProbability();
		x = 1.0 - x;
		tempEvent.add(participant);
		double prob = Double.parseDouble(tempProb);
		if (prob < 0.0) prob = 0.0;
		if (prob > x) prob = x;
		tempMap.put(participant, prob);
		prob = 1.0;
		for (Double elem : tempMap.values()) {
			prob -= elem;
		}
		tempProb = new Double(prob).toString();
	}

	public String getProb(Participant participant) {
		return tempMap.get(participant).toString();
	}

	public void commitEvent() {
		Iterator<SimpleRowKey> iterator = selection.getKeys();
		if (iterator.hasNext()) {
			SimpleRowKey row = iterator.next();
			AbstractEvent event = new AbstractEvent();
			for (Participant participant : tempEvent) {
				event.addParticipant(participant, tempMap.get(participant));
			}
			if (closingDate != null) event.setClosingDate(closingDate);
			else event.setClosingDate(new Date());
			event.setCreationDate(new Date());
			event.setWinner(null);
			dao.getGroupDAO().findAll().get(row.intValue()).addEvent(event);
			tempEvent = new ArrayList<Participant>();
			tempProb = "1.0";
			tempMap = new HashMap<Participant, Double>();
		}
	}

	@Create
	public void init() {
		eventDAO = dao.getEventDAO();
		participants = new ArrayList<Participant>();
		tempEvent = new ArrayList<Participant>();
		tempProb = "1.0";
		tempMap = new HashMap<Participant, Double>();
	}

	@Remove
	public void remove() {
		// DO NOTHING
	}

	public void setCurrentEvent(AbstractEvent currentEvent) {
		this.currentEvent = currentEvent;
	}

	public List<Participant> getParticipants() {
		if (currentEvent == null) return new ArrayList<Participant>();
		participants = new ArrayList<Participant>(currentEvent.getRates().keySet());
		return participants;
	}

	public double getRate(Participant participant) {
		return ((double)((int) ((1.0 / (0.1 + currentEvent.getRates().get(participant))) * 100.0)))/100.0;
	}

	public List<Participant> getTempEvent() {
		return tempEvent;
	}

	public void setTempEvent(List<Participant> tempEvent) {
		this.tempEvent = tempEvent;
	}

	public String getTempProb() {
		return tempProb;
	}

	public void setTempProb(String tempProb) {
		this.tempProb = tempProb;
	}

	public Map<Participant, Double> getTempMap() {
		return tempMap;
	}

	public void setTempMap(Map<Participant, Double> tempMap) {
		this.tempMap = tempMap;
	}

	public List<AbstractEvent> getAll() {
		all = eventDAO.findAll();
		return all;
	}

	public void removeFromTemp(Participant participant) {
		tempEvent.remove(participant);
		tempMap.remove(participant);
	}

	public void cancelEvent() {
		tempEvent = new ArrayList<Participant>();
		tempProb = "1.0";
		tempMap = new HashMap<Participant, Double>();
	}

	public SimpleSelection getSelection() {
		return selection;
	}

	public void setAsWinner(Participant participant) {
		currentEvent.setWinner(participant);
		updateUsersBets();
	}
	
	private void updateUsersBets() {
		
	}

	public AbstractEvent getCurrentEvent() {
		return currentEvent;
	}
}
